/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [CalendarPanel.java]
 * Creation Date        [10-Jul-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_02_gui.calendar;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * 日历面板
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class CalendarPanel extends JPanel {

	private static final long serialVersionUID = -8404037463287401216L;

	// 月份和年份下拉列表
	private final JComboBox<String> monthBox = new JComboBox<String>();
	private final JComboBox<String> yearBox = new JComboBox<String>();

	// 月份和年份标签
	private final JLabel monthLabel = new JLabel("月份");
	private final JLabel yearLabel = new JLabel("年份");

	// 查看和今天按钮
	private final JButton findButton = new JButton("查看");
	private final JButton todayButton = new JButton("今天");

	// 是否显示今天的标志
	private boolean todayFlag = false;

	// 获取今天的日期, 年份, 月份
	private final Calendar now_date = new GregorianCalendar();
	private final int now_year = now_date.get(Calendar.YEAR);
	private final int now_month = now_date.get(Calendar.MONTH);

	// 显示日期的按钮, 7行 * 7列, 第一行为星期的名字
	private final JButton[] weekButton = new JButton[7];
	private final String[] weekString = { "日", "一", "二", "三", "四", "五", "六" };
	private final JButton[] dateButton = new JButton[42];

	// 保存用户选择的年份和月份
	private String year_selected = null;
	private int month_selected = 0;

	private ActionListener listener = null;

	private void init() {
		Font font = new Font("Dialog", Font.BOLD, 14);
		yearLabel.setFont(font);
		monthLabel.setFont(font);
		findButton.setFont(font);
		todayButton.setFont(font);

		// 设定年份区间
		for (int i = now_year - 10; i <= now_year + 10; i++) {
			yearBox.addItem(i + "");
		}
		// 设定月份区间
		for (int i = 1; i < 13; i++) {
			monthBox.addItem(i + "");
		}

		// 设定年份和月份下拉列表为当前日期
		yearBox.setSelectedIndex(10);
		monthBox.setSelectedIndex(now_month);

		// 构建下拉列表框和控制按钮的面板
		JPanel panel1 = new JPanel();
		panel1.add(yearLabel);
		panel1.add(yearBox);
		panel1.add(monthLabel);
		panel1.add(monthBox);
		panel1.add(findButton);
		panel1.add(todayButton);

		findButton.addActionListener(listener);
		todayButton.addActionListener(listener);

		// 构建日期面板
		JPanel panel2 = new JPanel();
		panel2.setLayout(new GridLayout(7, 7, 3, 3));
		// 添加星期
		for (int i = 0; i < weekString.length; i++) {
			weekButton[i] = new JButton("");
			weekButton[i].setText(weekString[i]);
			weekButton[i].setForeground(Color.BLUE);
			panel2.add(weekButton[i]);
		}
		weekButton[0].setForeground(Color.RED);
		weekButton[6].setForeground(Color.RED);
		// 添加日期
		for (int i = 0; i < 42; i++) {
			dateButton[i] = new JButton("");
			panel2.add(dateButton[i]);
		}

		displayDate();

		setLayout(new BorderLayout());
		this.add(panel1, BorderLayout.NORTH);
		this.add(panel2, BorderLayout.CENTER);
	}

	public CalendarPanel(ActionListener listener) {
		this.listener = listener;
		init();
	}

	/**
	 * 显示当前的日期
	 */
	public void displayDate() {
		if (todayFlag) {
			// 要求显示今天的日期
			year_selected = now_year + "";
			month_selected = now_month;
		} else {
			// 从下拉列表中获取所选的年月
			year_selected = yearBox.getSelectedItem().toString();
			month_selected = monthBox.getSelectedIndex();
		}
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(Calendar.YEAR, Integer.parseInt(year_selected));
		calendar.set(Calendar.MONTH, month_selected);

		// 获得这个月的第一天
		calendar.set(Calendar.DAY_OF_MONTH, 1);

		int days = 0;// 某月的天数
		int day_of_week = 0; // 某月第一天是星期几

		month_selected += 1;

		// 计算某个月的天数
		/*
		 * if (month_selected == 1 || month_selected == 3 || month_selected == 5
		 * || month_selected == 7 || month_selected == 8 || month_selected == 10
		 * || month_selected == 12) { days = 31; } else if (month_selected == 4
		 * || month_selected == 6 || month_selected == 9 || month_selected ==
		 * 11) { days = 30; } else if (month_selected == 2) { if
		 * (calendar.isLeapYear(Integer.parseInt(year_selected))) { days = 29; }
		 * else { days = 28; } }
		 */
		days = calendar.getMaximum(Calendar.DAY_OF_MONTH);

		// 计算这个月的第一天是星期几
		day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		// System.out.println(day_of_week);
		int count = 1;
		// 绘制按钮, 首先要根据选定的月份的第一天是星期几来确定绘制的起始位置, day_of_week就是我们要绘制的起始位置
		for (int i = day_of_week; i < day_of_week + days; count++, i++) {
			if (i % 7 == 0 || i == 6 || i == 13 || i == 20 || i == 27
					|| i == 34 || i == 41) {
				// 如果是边界上的按钮, 文字用红色以标识周末, 但如果是当天日期, 要用蓝色表示
				if (i == day_of_week + now_date.get(Calendar.DATE) - 1) {
					dateButton[i].setForeground(Color.BLUE);
					dateButton[i].setText(count + "");
				} else {
					dateButton[i].setForeground(Color.RED);
					dateButton[i].setText(count + "");
				}
			} else {
				// 如果不是边界上的按钮, 文字用黑色标识普通日期, 但如果是当天日期, 要用蓝色表示
				if (i == day_of_week + now_date.get(Calendar.DATE) - 1) {
					dateButton[i].setForeground(Color.BLUE);
					dateButton[i].setText(count + "");
				} else {
					dateButton[i].setForeground(Color.BLACK);
					dateButton[i].setText(count + "");
				}
			}
		}

		// 对于没有日期显示的空按钮的处理
		if (day_of_week == 0) {
			// 如果第一天是周日, 那么将后面的按钮全部置空
			for (int i = days; i < 42; i++) {
				dateButton[i].setText("");
			}
		} else {
			// 如果第一天不是周日, 将前后按钮都置空
			for (int i = 0; i < day_of_week; i++) {
				dateButton[i].setText("");
			}
			for (int i = day_of_week + days; i < 42; i++) {
				dateButton[i].setText("");
			}
		}
	}

	public boolean isTodayFlag() {
		return todayFlag;
	}

	public void setTodayFlag(boolean todayFlag) {
		this.todayFlag = todayFlag;

	}

	public void setCalendarAsToday() {
		yearBox.setSelectedIndex(10);
		monthBox.setSelectedIndex(now_month);
	}

}
